package com.tanhua.server.service;

import com.tanhua.commons.template.AliyunOssTemplate;
import com.tanhua.commons.template.AliyunSmsTemplate;
import com.tanhua.commons.template.BaiduAipFaceTemplate;
import com.tanhua.commons.template.HuanXinTemplate;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.UserFrozen;
import com.tanhua.domain.vo.ErrorResult;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.dubbo.api.UserFrozenApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.server.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
public class UserService {
    @Value("${tanhua.secret}")
    private String secret;
    @Reference
    private UserApi userApi;
    @Reference
    private UserInfoApi userInfoApi;
    @Reference
    private UserFrozenApi userFrozenApi;
    @Autowired
    private AliyunSmsTemplate smsTemplate;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private BaiduAipFaceTemplate aipFaceTemplate;
    @Autowired
    private AliyunOssTemplate ossTemplate;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    //发送验证码
    public ResponseEntity sendVerificationCode(String mobile) {
        //验证当前用户有没有被冻结
        User user = userApi.findByMobile(mobile);
        if (user != null) {
            UserFrozen userFrozen = userFrozenApi.findUserFrozenByUserId(user.getId());
            if (userFrozen != null && userFrozen.getFreezingRange() == 1) {
                return ResponseEntity.status(500).body(ErrorResult.loginFrozen(userFrozen.getOutTime()));
            }
        }
        //发送验证码
//        String code = smsTemplate.sendSms(mobile);
        //测试：
        String code = "123456";
        //将code存入redis 5 min
        redisTemplate.opsForValue().set("CODE_" + mobile, code, Duration.ofMinutes(5));
        log.info("sendVerificationCode: 手机号：{} 验证码：{}", mobile, code);
        return ResponseEntity.ok(null);
    }

    //校验验证码
    public ResponseEntity loginVerification(String mobile, String verificationCode) {
        //1. 从redis中获取验证码
        String code = redisTemplate.opsForValue().get("CODE_" + mobile);
        if (code == null || !code.equals(verificationCode)) {
            return ResponseEntity.status(500).body(ErrorResult.smsInvalid());
        }
        //2. 验证码通过，将redis中得验证清除
        redisTemplate.delete("CODE_" + mobile);
        //3. 根据手机号查询用户，如果存在，则登录。不存在，则注册
        User user = userApi.findByMobile(mobile);
        boolean isNew = false;
        if (user == null) {
            //注册
            user = new User();
            user.setMobile(mobile);
            //用户密码加密
            user.setPassword(DigestUtils.md5Hex("123456"));
            long id = userApi.save(user);
            user.setId(id);
            isNew = true;
            huanXinTemplate.register(user.getId().toString(), "123456");
        }
        //登录或注册成功后发送mq消息
        Map<String, Object> message = new HashMap<>();
        message.put("userId", user.getId());
        //0101登录 0102注册
        message.put("type", isNew ? "0102" : "0101");
        message.put("place", "天津-滨海新区");
        message.put("date", new DateTime().toString("yyyy-MM-dd"));
        rocketMQTemplate.convertAndSend("tanhua-log", message);
        log.info("【发送MQ消息】topic:{}, message{}", "tanhua-log", message);

        //4. 使用token存入redis,
        String token = JwtUtils.createToken(user, secret);
        //token在redis中存储TOKEN_userId:token,存储时间 1h
        redisTemplate.opsForValue().set("TOKEN_" + user.getId(), token, Duration.ofHours(1));
        //5. 构造返回值类型
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("isNew", isNew);
//        log.info("登录检验返回token：{}", token);
        return ResponseEntity.ok(result);
    }

    /**
     * 完善用户信息
     */
    public ResponseEntity saveUserInfo(UserInfo userInfo) {
        //保存用户信息
        UserInfo info = userInfoApi.findById(userInfo.getId());
        if (info == null) {
            userInfoApi.save(userInfo);
        } else {
            userInfoApi.update(userInfo);
        }
        log.info("用户信息保存成功");
        return ResponseEntity.ok(null);
    }

    /**
     * 保存用户头像
     */
    public ResponseEntity saveAvatar(MultipartFile headPhoto, Long userId) throws IOException {
        //1. 对图片人脸识别
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        if (!detect) {
            return ResponseEntity.status(500).body(ErrorResult.faceDetectFailed());
        }
        //2. 保存图片到oss
        String url = ossTemplate.upload(headPhoto.getInputStream(), headPhoto.getOriginalFilename());
        //3. 将url保存到数据库
        UserInfo userInfo = new UserInfo();
        userInfo.setId(userId);
        userInfo.setAvatar(url);
        userInfo.setCoverPic(url);
        userInfoApi.update(userInfo);
        log.info("头像保存成功");
        return ResponseEntity.ok(null);
    }
}
